package br.com.foxinline.manager.criar;

import br.com.foxinline.modelo.Distribuicao;
import br.com.foxinline.modelo.DistribuicaoItem;
import br.com.foxinline.modelo.Selo;
import br.com.foxinline.modelo.TipoSelo;
import br.com.foxinline.modelo.Usuario;
import br.com.foxinline.servico.DistribuicaoItemServico;
import br.com.foxinline.servico.DistribuicaoServico;
import br.com.foxinline.servico.SeloServico;
import br.com.foxinline.servico.TipoSeloServico;
import br.com.foxinline.servico.UsuarioServico;
import br.com.foxinline.utilitario.Mensagem;
import java.io.Serializable;
import java.util.*;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;

/**
 *
 * @author cadomeireles
 */
@ViewScoped
@ManagedBean
public class ManagerCriarDistribuicao implements Serializable {

    @EJB
    UsuarioServico usuarioServico;
    @EJB
    TipoSeloServico tipoSeloServico;
    @EJB
    SeloServico seloServico;
    @EJB
    DistribuicaoServico distribuicaoServico;
    @EJB
    DistribuicaoItemServico distribuicaoItemServico;
    
    private Distribuicao distribuicao;    
    private DistribuicaoItem distribuicaoItem;
    private List<DistribuicaoItem> distribuicaoItens;
    private List<Selo> selosRemovidos;

    private String editarId;
    
    @PostConstruct
    public void init() {
        instanciar();
        delegar();
    }

    private void instanciar() {
        this.distribuicao = new Distribuicao();
        this.distribuicao.setRecebedor(new Usuario());
        this.distribuicaoItem = new DistribuicaoItem();
        this.distribuicaoItens = new ArrayList<DistribuicaoItem>();
        this.selosRemovidos = new ArrayList<Selo>();
    }
    
    private void delegar() {
        Map<String, String> parametros = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
        this.editarId = parametros.get("distribuicaoId");
        
        if (this.editarId != null) {
            this.distribuicao = distribuicaoServico.pesquisar(Long.parseLong(this.editarId));
            this.distribuicaoItens = distribuicaoServico.obterItens(this.distribuicao);
        }
    }

    public void adicionarDistribuicao() {

        Integer quantidade = seloServico.quantidadePorTipo(this.distribuicaoItem.getTipoSelo());

        if (quantidade >= this.distribuicaoItem.getQuantidade()) {
            this.distribuicaoItens.add(this.distribuicaoItem);
            this.distribuicaoItem = new DistribuicaoItem();
        } else {
            Mensagem.messagemWarn("Não há selos suficientes no estoque.");
        }

    }
    
    public void editarDistribuicao(DistribuicaoItem distribuicaoItem) {
        this.distribuicaoItem = distribuicaoItem;
        this.distribuicaoItens.remove(distribuicaoItem);
    }

    public void removerDistribuicao(DistribuicaoItem distribuicaoItem) {
        this.distribuicaoItens.remove(distribuicaoItem);
        
        if (distribuicaoItem.getId() != null) {
            this.selosRemovidos.addAll(distribuicaoItem.getSelos());
        }
    }    

    public void distribuir() {

            for (DistribuicaoItem item : this.distribuicaoItens) {                

                // nova distribuição
                if (item.getId() == null) {
                    List<Selo> selos = seloServico.obterSelos(item.getTipoSelo(), item.getQuantidade(), false);
                    item.setSelos(selos);

                // atualizar distribuição
                } else {
                    DistribuicaoItem itemAtual = distribuicaoItemServico.pesquisar(item.getId());

                    Integer quantidade = item.getQuantidade() - itemAtual.getQuantidade();

                    // adicionar selos
                    if (quantidade > 0) {
                        List<Selo> selos = seloServico.obterSelos(item.getTipoSelo(), quantidade, false);
                        item.getSelos().addAll(selos);
                    // remover selos
                    } else if (quantidade < 0) {
                        List<Selo> selos = seloServico.obterSelos(item.getTipoSelo(), item.getQuantidade(), true);
                        item.getSelos().retainAll(selos);
                        seloServico.distribuicao(selos, false);
                    }
                }

            }

    }
    
    public void limpar() {
        this.distribuicaoItem = new DistribuicaoItem();
    }
    
    public void salvar() {
        String mensagem;
        boolean salvo;

        // setar selos como distribuídos
        for (DistribuicaoItem item : this.distribuicaoItens) {
//            seloServico.distribuicao(item.getSelos(), true);
            for (Selo selo : item.getSelos()) {
                selo.setDistribuido(true);
                seloServico.atualizar(selo);
            }
        }
        
        // selos removidos
        if (this.selosRemovidos.size() > 0) {
            seloServico.distribuicao(this.selosRemovidos, false);
        }

        this.distribuicao.setDistribuicaoItens(this.distribuicaoItens);        
        
        // salvar
        if (distribuicao.getId() == null) {
            distribuicaoServico.salvar(this.distribuicao);
            salvo = true;
        // atualizar
        } else {
            distribuicaoServico.atualizar(this.distribuicao);
            salvo = false;
        }

        // setar distribuição do selo
        for (DistribuicaoItem item : this.distribuicaoItens) {
            for (Selo selo : item.getSelos()) {
                selo.setDistribuicao(this.distribuicao);
                seloServico.atualizar(selo);
            }
        }

        if (salvo) {
            instanciar();
            mensagem = "Distribuição realizada com sucesso!";
        } else {
            mensagem = "Distribuição atualizada com sucesso!";
        }        

        Mensagem.messagemInfo(mensagem);
    }
    
    public List<Usuario> autocompletarUsuario(String query) {
        return usuarioServico.autocompletar(query);
    }
    
    public List<TipoSelo> autocompletarTipoSelo(String query) {
        return tipoSeloServico.autocompletar(query);
    }
    
    public Distribuicao getDistribuicao() {
        return distribuicao;
    }

    public void setDistribuicao(Distribuicao distribuicao) {
        this.distribuicao = distribuicao;
    }

    public DistribuicaoItem getDistribuicaoItem() {
        return distribuicaoItem;
    }

    public void setDistribuicaoItem(DistribuicaoItem distribuicaoItem) {
        this.distribuicaoItem = distribuicaoItem;
    }

    public List<DistribuicaoItem> getDistribuicaoItens() {
        return distribuicaoItens;
    }

    public void setDistribuicaoItens(List<DistribuicaoItem> distribuicaoItens) {
        this.distribuicaoItens = distribuicaoItens;
    }

    public List<Selo> getSelosRemovidos() {
        return selosRemovidos;
    }

    public void setSelosRemovidos(List<Selo> selosRemovidos) {
        this.selosRemovidos = selosRemovidos;
    }

}
